package com.temdemo.utils.filterguration;

import com.alibaba.fastjson.JSON;
import com.temdemo.utils.jwt.JwtTokenUtil;
import com.temdemo.utils.restful.AjaxJson;
import com.temdemo.utils.threadLocal.RequestHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Map;

@Order(1)
@Component
@WebFilter(filterName = "ConfFilter", urlPatterns = {"/*"})
public class ConfFilter implements Filter {
    @Value("${excludedPageArray}")
    private String excludedPageArray;
 /*   @Autowired
    private SystemUserMapper systemUserMapper;*/


    private static String[] SqlStr1 = {"and", "exec", "execute", "insert", "select", "delete", "update", "count", "drop", "chr", "mid", "master", "truncate", "char", "declare", "sitename", "net user", "xp_cmdshell", "like", "and", "exec", "execute", "insert", "create", "drop", "table", "from", "grant", "use", "group_concat", "column_name", "information_schema.columns", "table_schema", "union", "where", "select", "delete", "update", "order", "by", "count", "chr", "mid", "master", "truncate", "char", "declare", "or", "*", "'", ";", "or", "+", "//", "/", "%", "#","\\r","\\n"};//词语


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //String url = request.getRequestURI();
        if (cheakParameter(request)==false) {
            AjaxJson ajaxJson = new AjaxJson(500, false, "操作失败", "请求参数存在特殊字符", null, null);
            OutputStream out = response.getOutputStream();
            out.write(JSON.toJSONString(ajaxJson).getBytes("UTF-8"));
            out.flush();
            return;
        }
        if (true) {//excludedPass(url)
            filterChain.doFilter(request, response);
            return;
        } else {
            if (isLogin(request, response) == true) {
                filterChain.doFilter(request, response);
                return;
            } else {
                AjaxJson ajaxJson = new AjaxJson(401, false, "操作失败", "登录验证失效,请重新登录", null, null);
                OutputStream out = response.getOutputStream();
                out.write(JSON.toJSONString(ajaxJson).getBytes("UTF-8"));
                out.flush();
                return;
            }
        }
    }

    @Override
    public void destroy() {

    }

    /**
     * 忽略列表
     *
     * @param url
     * @return
     */
    private boolean excludedPass(String url) {
        String[] arrayslist = excludedPageArray.split(",");
        for (String passurl : arrayslist) {
            if (passurl.indexOf("*") != -1) {
                if (url.startsWith(passurl.replace("*", ""))) {
                    return true;
                }
            } else {
                if (url.equals(passurl)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 登录验证 获取请求头
     *
     * @param request
     * @return
     */
    private boolean isLogin(HttpServletRequest request, HttpServletResponse response) {
        try {
            String url = request.getRequestURI();
            final String token = getJwt(request);
            if (token == null || ObjectUtils.isEmpty(token)) {
                return false;
            }
            if (ObjectUtils.isEmpty(token)) {
                return false;
            }
            JwtTokenUtil jwt = new JwtTokenUtil();
            //验证token格式是否正确
            jwt.parseToken(token);
            //验证时间
            if (jwt.isTokenExpired(token) == true) {
                return false;
            }
            // TreadLocal 赋值
            Map<String, Object> map = (Map) jwt.getClaimFromToken(token);
            RequestHolder.add(map);
            //刷新token
            return refreshToken(map, response);
        }catch (Exception e){
            System.out.println(e.getMessage());
            return false;
        }
    }

    /**
     * 获取token
     *
     * @param req
     * @return
     */
    private String getJwt(ServletRequest req) {
        HttpServletRequest request = (HttpServletRequest) req;
        final String authHeader = request.getHeader("Authorization");
        if (authHeader == null || ObjectUtils.isEmpty(authHeader)) {
            return null;
        }
        final String token = authHeader.substring(7);// bearer;
        return token;
    }

    /**
     * @return void
     * @Description //刷新token  验证 账号 实时状态
     * @Author 晨曦
     * @Date 2019/12/11 15:56
     * @Param [map, response]
     */
    private Boolean refreshToken(Map map, HttpServletResponse response) {
        JwtTokenUtil jwt = new JwtTokenUtil();
        Integer count = 0;//systemUserMapper.countStateById((Integer) map.get("id"));
        if (count == 0) {
            response.setHeader("Authorization", null);
            return false;
        } else {
            String token = jwt.generateToken((Integer) map.get("id"), (String) map.get("sub"), jwt.getRandomKey());
            response.setHeader("Authorization", token);
            return true;
        }
    }


    //过滤非法字符

    private Boolean cheakParameter(HttpServletRequest request) {
        try{
            //设置字符集
            request.setCharacterEncoding("utf-8");
            Enumeration names = request.getParameterNames();
            //得到用户提交的信息
            while (names.hasMoreElements()) {

                String name = (String) names.nextElement();

                String message = request.getParameter(name);

                if (ObjectUtils.isEmpty(message) == false) {
                    //遍历集合
                    for (String s : SqlStr1) {
                        //s遍历到集合中的每一个非法字符
                        //在控制台打印非法字符
                        //返回字符中indexof（string）中字串string在父串中首次出现的位置，
                        // 从0开始！没有返回-1
                        //message.indexOf(s)非法字符在用户提交的信息中出现的位置，
                        // 如果非法字符在用户信息中没有出现，则返回-1（=-1），
                        // 如果非法字符在用户信息中有出现，就相当于不等于-1
                        if ((message.indexOf(s)) != -1) {
                            return false;
                        }
                    }
                }
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return true;
    }

}
